<?php

class lb_user{
	
	public $user_id	= -1;
	public $username 	= '';
	protected $group_id = -1;
	
	public $read	= true;
	public $write	= false;
	
	protected $errs	= array();
	
	/**
	 * constructor of lb_user
	 * 
	 * @access	public
	 * @author 	Omid Mottaghi
	 */
	function __construct(){
		global $lb;
		
		//load user_id from session
		if($this->user_id  = $lb['session']->get('user_id')){
			$this->load_user();
		}
	}
	
	/**
	 * Load User informations
	 *
	 * @access	protected
	 * @author	Armin Borumand
	 */
	function load_user(){
		global $lb;
		
		$query = 'SELECT A.username, B.group_id
				FROM #__user AS A
			  INNER  JOIN #__usergroup AS B ON A.user_id = B.user_id
				WHERE A.user_id = #';
		$params = array(
				array($this->user_id, 'int')
				);
								
		$result = $lb['db']->query($query, $params);
		if($result['num_of_rows'] == 1){
			$this->username = $result['rows'][0]['username'];
			$this->group_id   = $result['rows'][0]['group_id'];		
		}else{
			$this->errs[] = LANG_USER_ERROR_LOAD_INFO;
			$this->logout();
			$lb['error'] = $this->get_errors();
			$lb['task'] = 'error';
		}
	}
	
	/**
	 * user login
	 * 
	 * @access	public
	 * @author	Omid Mottaghi
	 * @author	Armin Borumand
	 * @param	string	username of user
	 * @param 	string	password of user
	 * @param 	boolean	use cookie or not
	 * @return 	boolean	if logged in return true, else return false
	 */
	function login($user, $pass, $rem=false){
		global $lb;
		
		//If user logged in!
		if($this->user_id > 0){
			$this->errs[] = LANG_USER_ALREADY_LOGGED;
			return false;
		}

		$params = array (
				array ($user, 'string'),
				array ($pass, 'password')
				);
	
		$query = 'SELECT user_id, username, verify
				FROM #__user
				WHERE username = # AND password = #';		
				
		$result = $lb['db']->query($query, $params);
		
		// if user exist, set sessions
		if($result['num_of_rows'] == 1){
			//Regenerate session
			$lb['session']->regenerate();
			
			//Set session variables
			//$lb['session']->set('logged', 1);
			$lb['session']->set('user_id', $result['rows'][0]['user_id']);
			//$lb['session']->set('username', $result['rows'][0]['username']);
			
			// Identify user
			$this->user_id = $result['rows'][0]['user_id'];
			$this->group_id = $this->group_id();
			
			//if user want to be remembered and set cookie
			if($rem){
				//Set a unique id
				$uid = lb_system::hash($result['rows'][0]['user_id'] . $result['rows'][0]['verify']);
				
				//Set cookies
				lb_system::setcookie('uid', $uid);
				lb_system::setcookie('user', $result['rows'][0]['user_id']);
			}
		
			return true;
		}else{
			$this->errs[] = LANG_INVALID_USER_OR_PASS;
			return false;
		}
	}
	
	/**
	 * user login from cookie
	 *
	 * @access	public
	 * @author	Armin Borumand
	 * @return	boolean	true on success and false on failure
	 */
	function login_from_cookie() {
		global $lb;
		
		//If user logged in!
		if($this->user_id > 0){
			$this->errs[] = LANG_ALREADY_LOGGED_IN;
			return false;
		}
		
		//Get required cookie information
		$req_user_id = lb_system::getcookie('user');//for specify user
		$req_uid     = lb_system::getcookie('uid');//as authentication code (not user password)
		
		//If cookie not set!
		if($req_user_id == false || $req_uid == false){
			return false;
		}
		
		$params = array (
				array ($req_user_id, 'int')
				);
		
		$query = 'SELECT user_id, username, verify
				FROM #__user
				WHERE user_id = #';
		
		$result = $lb['db']->query($query, $params);
		
		//If user not found
		if($result['num_of_rows'] != 1){
			return false;
		}
		
		//Make an unique identifier from user_id and verify fields
		$uid = lb_system::hash($result['rows'][0]['user_id'] . $result['rows'][0]['verify']);
		
		if($uid == $req_uid){
			//S1: setting session
			$lb['session']->regenerate();
			//$lb['session']->set('logged', 1);
			$lb['session']->set('user_id', $result['rows'][0]['user_id']);
			$lb['session']->set('username', $result['rows'][0]['username']);
			
			//S2: User register
			$this->user_id  = $result['rows'][0]['user_id'];
			$this->username = $result['rows'][0]['username'];
			$this->group_id = $this->group_id();
			
			//S3: New Verify
			$new_verify = $this->update_verify();
			$uid = lb_system::hash($result['rows'][0]['user_id'] . $new_verify);
			lb_system::setcookie('uid', $uid);
			
			//S4: finish
			return true;
		}else{
			return false;
		}
		
	}
	
	/**
	*return user logging status
	*
	* @access	public
	* @author	Armin Borumand
	* @return	int	user logging status(have been set in sessuin)
	*/
	function logged(){

		if($this->user_id > 0){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * set current user's accessibility for current page
	 * 
	 * @access	public
	 * @author Omid Mottaghi
	 * @return 	boolean	if there is no problem return true, else return false
	 */
	function get_permissions(){
		global $lb;
		
		//if user didn't log in
		if($this->user_id < 0){
			return true;
		}
		
		$params = array (
			array ($lb['page']->page, 'string'),
			array ($this->user_id, 'string')
		);
		
		$query = 'SELECT pg.type AS type
				  FROM
				  #__usergroup 	AS ug,
				  #__group 		AS g,
				  #__pagegroup 	AS pg,
				  #__page 		AS p
				  WHERE
				  ug.group_id 	= g.group_id
				  AND g.group_id 	= pg.group_id
				  AND pg.page_id 	= #
				  AND ug.user_id 	= #';
		
		$result = $lb['db']->query($query, $params);
		
		// if user exist, set sessions
		if($result['num_of_rows'] > 0){
			// set page permissions
			if($result['rows'][0]['type']=='write'){
				$this->read  = true;
				$this->write = true;
			}elseif($result['rows'][0]['type']=='read'){
				$this->read  = true;
				$this->write = false;
			}else{
				$this->read  = false;
				$this->write = false;
			}
			
			return true;
		}else{
		
			return false;
		}
	}
	
	/**
	 * return current user's read accessibility for current page
	 * 
	 * @access	public
	 * @author	Omid Mottaghi
	 * @return 	integer		return 1 if user can read this page
	 */
	function can_read(){
		return $this->read;
	}
	
	/**
	 * return current user's write accessibility for current page
	 * 
	 * @access	public
	 * @author	Omid Mottaghi
	 * @return 	integer		return 1 if user can edit this page
	 */
	function can_write(){
		return $this->write;
	}
	
	/**
	 * return current user's group id
	 * 
	 * @access	public
	 * @author 	Armin Borumand
	 * @params	integer	user id
	 * @return 	integer	group id on success and false on failure
	 */
	function group_id($user_id=-1){
		global $lb;
		
		//If param not set
		if($user_id < 0){
			if($this->group_id < 0){
				$user_id = $this->user_id;
			}else{
				return $this->group_id;
			}
		}
		//If user not specified
		if($user_id < 0){
			return false;
		}
		
		$params = array (
				array($user_id ,'int')
				);
		
		$result = $lb['db']->query('SELECT group_id 
						FROM #__usergroup
						WHERE user_id=#', $params);
									
		if($result['num_of_rows'] == 1){
			return $result['rows'][0]['group_id'];
		}else{
			return false;
		}
		
	}
	
	/**
	*user logout
	*
	* @access	public
	* @author	Armin borumand
	* @return	boolean	true
	*/
	function logout(){
		global $lb;
		
		// Remove user id and group id and username
		$this->user_id		= -1;
		$this->group_id	= -1;
		$this->username = '';
		
		//Remove session
		//$lb['session']->remove('logged');
		$lb['session']->remove('user_id');
		//$lb['session']->remove('username');
		
		//Remove cookies
		lb_system::setcookie('uid', '', false);
		lb_system::setcookie('user', '', false);
		
		return true;
	}
	
	/**
	*return lb_user errors
	*
	* @access	public
	* @author	Armin Borumand
	* @return	array		lb_user errors
	*/
	function get_errors(){
		$errors = $this->errs;
		$this->errs = array();
		return $errors;
	}
	
	/**
	* Add new user
	*
	* @access	public
	* @author	Armin Borumand
	* @param	string	user name
	* @param	string	password
	* @param	string	email
	* @param	int		group id
	* @return	int/bool	on success return user id and on failure return false
	*/
	function add_user($user, $pass, $email, $group_id){
		global $lb;
		
		if($user == '' || $pass == ''){
			$this->errs[] = LANG_USER_ERROR_EMPTY;
			return false;
		}
		
		if(self::user_id($user)){
			$this->errs[] = LANG_USER_ERROR_DUPLICATE;
			return false;
		}
		
		//Generate a verify code
		$verify = lb_user::make_verify();
		
		$params = array(
				array($user, 'text'),
				array($pass, 'password'),
				array($email, 'text'),
				array($verify, 'text')
				);
		$query  = 'INSERT INTO #__user (username, password, email, verify) VALUES (#, #, #, #)';
		$result = $lb['db']->query($query, $params);
		
		//If insert in user table
		if($result['num_of_rows'] == 1){
			$user_id = $result['insert_id'];
			
			$params = array(
						array($user_id, 'int'),
						array($group_id, 'int')
						);
			$query  = 'INSERT INTO #__usergroup (user_id, group_id) VALUES (#, #)';
			$result = $lb['db']->query($query, $params);
			
			//If insert in usergroup table
			if($result['num_of_rows'] == 1){
				return $user_id;
			}else{
				//If can't insert in usergroup
				$params = array(
							array($user_id, 'int')
							);
				$query = 'DELETE FROM #__user WHERE user_id = #';
				$lb['db']->query($query, $params);
				return false;
			}
			
		}else{
			return false;
		}
	}

	/**
	* Edit a user information
	*
	* @access	public
	* @author	Armin Borumand
	* @param	string	password
	* @param	string	email
	* @param	string	user name
	* @param	int		user id
	* @return	boolean	on success return true and on failure return false
	*/
	function edit_user($user, $pass, $email, $user_id=-1){
		global $lb;
		$update = '';
	
		//If user_id param not set
		if($user_id < 0){
			$user_id = $this->user_id;
		}
		//If user not specified
		if($user_id < 0){
			$this->errs[] = LANG_USER_ERROR_SPECIFY;
			return false;
		}
		
		if($user != ''){
			$update  .= 'username = #, ';
			$params[] = array($user, 'text');
		}
		if($pass != ''){
			$update  .= 'password = #, ';
			$params[] = array($pass, 'password');
		}
		if($email != ''){
			$update  .= 'email = #, ';
			$params[] = array($email, 'text');
		}
		
		if($update == ''){
			return true;
		}
		
		$update		= substr($update, 0, strlen($update)-2);
		
		$params[]	= array($user_id, 'int');
		$query 		= 'UPDATE #__user SET ' . $update . ' WHERE user_id = #';;
		
		$result		= $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] == 1){
			return true;
		}else{
			$this->errs[] = LANG_DATABASE_ERROR;
			return false;
		}
	}
	
	/**
	* Change user group
	*
	* @access	public
	* @author	Armin Borumand
	* @param	integer	user id
	* @param	integer	group id
	* @return	boolean	on success return true and on failure return false
	*/
	function edit_usergroup($user_id, $group_id){
		global $lb;
		
		$params = array(
					array($group_id, 'int'),
					array($user_id, 'int')
					);
		$query  = 'UPDATE #__usergroup SET group_id = # WHERE user_id = #';
		$result = $lb['db']->query($query, $params);

		if($result['num_of_rows'] == 1){
			if($this->user_id == $user_id){
				$this->logout();
			}
			return true;
		}else{
			return false;
		}
	}
	
	/**
	* Remove a user from db
	*
	* @access	public
	* @author	Armin Borumand
	* @param	int	user id
	* @return	bool	true or false
	*/
	function remove_user($user_id){
		global $lb;
		
		$params = array(
				array($user_id, 'int')
				);
		$query  = 'DELETE FROM #__user WHERE user_id = #';
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] == 1){
			//if use FK not need
			$query = 'DELETE FROM #__usergroup WHERE user_id = #';
			$lb['db']->query($query, $params);
			
			return true;
		}else{
			return false;
		}
	}
	
	/**
	* Update user verify
	*
	* @access	protected
	* @author	Armin Borumand
	* @param	int		user id
	* @return	string/bool	user new verify value or false in failure
	*/
	function update_verify($user_id=-1){
		global $lb;
		
		//If user_id param not set
		if($user_id < 0){
			$user_id = $this->user_id;
		}
		//If user not specified
		if($user_id < 0){
			return false;
		}
		
		$new_verify = lb_user::make_verify();
		
		$params = array(
					array($new_verify, 'text'),
					array($user_id, 'int')					
					);
		$query = 'UPDATE #__user SET verify = # WHERE user_id = #';
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] == 1){
			return $new_verify;
		}else{
			return false;
		}
	}
	
	/**
	* Make a verify value
	* 
	* @access	protected
	* @author	Armin Borumand
	* @return	string	generated verify value
	*/
	function make_verify(){
		return rand (10000, 999999);
	}
	
	/**
	* Return user id from username
	*
	* @access	public
	* @author	Armin Borumand
	* @param	string	username
	* @return	int/bool	user id or false
	*/
	function user_id($username=false){
		global $lb;
		
		if($username == false){
			return $this->user_id;
		}
		
		$query  = 'SELECT user_id FROM #__user WHERE username = #';
		$params = array(	
					array($username, 'text')
					);
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] > 0){	
			return $result['rows'][0]['user_id'];
		}else{	
			return false;
		}
	}
	
	/**
	* Return username from user id
	*
	* @access	public
	* @author	Armin Borumand
	* @param	int					user id
	* @return	string/bool	username or false
	*/
	function username($user_id=false){
		global $lb;
		
		if($user_id == false){	
			return $this->username;
		}
		
		$query  = 'SELECT username FROM #__user WHERE user_id = #';
		$params = array(	
					array($user_id, 'int')
					);
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] > 0){	
			return $result['rows'][0]['username'];
		}else{	
			return false;
		}
	}

	/**
	* Return number of users
	*
	* @access	public
	* @author	Armin Borumand
	* @return	int	number of users
	*/
	function count(){
		global $lb;
		
		$result = $lb['db']->query('SELECT count(*) AS count FROM #__user', array());
		
		if($result['num_of_rows'] > 0){
			return $result['rows'][0]['count'];
		}else{
			return -1;
		}
	}
	
	/**
	* Search in users
	* 
	* @access	public
	* @author	Armin Borumand
	* @param	string	username
	* @return	array		usernames
	*/
	function search($name=''){
		global $lb;
		
		$query  = 'SELECT username 
				FROM #__user 
				WHERE username LIKE #
				UNION SELECT count(*) 
					FROM #__user';
		$params = array(
				array('%' . $name . '%', 'text')
				);
					
		$result = $lb['db']->query($query, $param);
					
		//if there are an error in database result
		if($result['num_of_rows'] < 1){
			$result['rows'] = array();
		}else{
			//specify num of rows
			$result['num_of_rows'] = intval($result['rows'][$result['num_of_rows'] - 1]['username']);
			array_pop($result['rows']);
		}
		
		return $result;
	}
	
	/**
	* Specify user
	*
	* @access	public
	* @author	Armin Borumand
	* @return	true if user is registered user and false if not
	*/
	function is_user(){
		if($this->user_id() > 0){
			return true;
		}else{
			return false;
		}
	}

	/**
	* Specify superuser
	*
	* @access	public
	* @author	Armin Borumand
	* @return	true if user is superuser and false if not
	*/
	function is_su(){
		if($this->group_id == lb_group::SU_ID){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	* Specify moderator
	*
	* @access	public
	* @author	Armin Borumand
	* @return	true if user is moderator and false if not
	*/	
	function is_moderator(){
		if($this->group_id == lb_group::MDR_ID){
			return true;
		}else{
			return false;
		}
	}
	
}

?>
